package com.museyu.controller;

import com.museyu.model.GameRoom;
import com.museyu.model.GameState;
import com.museyu.model.Player;
import com.museyu.service.GameService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.messaging.handler.annotation.MessageMapping;
import org.springframework.messaging.handler.annotation.SendTo;
import org.springframework.messaging.handler.annotation.Payload;
import org.springframework.messaging.handler.annotation.DestinationVariable;
import org.springframework.messaging.simp.SimpMessageHeaderAccessor;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import org.springframework.messaging.simp.SimpMessagingTemplate;
import org.springframework.messaging.handler.annotation.Header;

import javax.servlet.http.HttpServletRequest;
import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.ConcurrentHashMap;

@Controller
@RequestMapping("/api/game")
public class GameController {
    private static final Logger logger = LoggerFactory.getLogger(GameController.class);
    private final AtomicInteger onlinePlayers = new AtomicInteger(0);
    private final Map<String, String> sessionToPlayerName = new ConcurrentHashMap<>();

    @Autowired
    private GameService gameService;

    @Autowired
    private SimpMessagingTemplate messagingTemplate;

    @PostMapping("/room")
    @ResponseBody
    public ResponseEntity<?> createRoom(HttpServletRequest request) {
        logger.info("创建新房间请求");
        try {
            String sessionId = request.getSession().getId();
            if (sessionId == null) {
                throw new RuntimeException("无法获取会话ID");
            }

            GameRoom room = gameService.createRoom();
            Player player = gameService.joinRoom(room.getId(), "房主");
            gameService.setPlayerSessionId(player.getId(), sessionId);
            
            logger.info("创建房间成功: roomId={}, playerId={}, sessionId={}, isRoomOwner={}", 
                room.getId(), player.getId(), sessionId, room.isRoomOwner(player.getId()));
            
            // 广播房间状态更新
            GameState gameState = gameService.convertToGameState(room);
            gameState.setType("ROOM_UPDATE");
            messagingTemplate.convertAndSend("/topic/game/" + room.getId(), gameState);
            
            return ResponseEntity.ok(Map.of("room", room, "player", player));
        } catch (RuntimeException e) {
            logger.error("创建房间失败: {}", e.getMessage());
            return ResponseEntity.badRequest().body(Map.of("error", e.getMessage()));
        }
    }

    @PostMapping("/room/{roomId}/join")
    @ResponseBody
    public ResponseEntity<?> joinRoom(@PathVariable String roomId, @RequestBody Map<String, String> requestMap, HttpServletRequest request) {
        try {
            String playerName = requestMap.get("name");
            if (playerName == null || playerName.trim().isEmpty()) {
                return ResponseEntity.badRequest().body(Map.of("error", "玩家名称不能为空"));
            }

            String sessionId = request.getSession().getId();

            Player player = gameService.joinRoom(roomId, playerName);
            gameService.setPlayerSessionId(player.getId(), sessionId);
            logger.info("玩家加入房间成功: roomId={}, playerId={}, playerName={}", roomId, player.getId(), playerName);
            
            // 广播房间状态更新
            GameRoom room = gameService.getRoom(roomId);
            if (room != null) {
                // 给所有玩家发送更新后的房间状态
                GameState gameState = gameService.convertToGameState(room);
                gameState.setType("ROOM_UPDATE");
                messagingTemplate.convertAndSend("/topic/game/" + roomId, gameState);
            }
            
            return ResponseEntity.ok(player);
        } catch (Exception e) {
            logger.error("加入房间失败: {}", e.getMessage());
            return ResponseEntity.badRequest().body(Map.of("error", e.getMessage()));
        }
    }

    @MessageMapping("/game/start")
    public void startGame(@Payload Map<String, String> payload) {
        logger.info("收到开始游戏请求: payload={}", payload);
        
        String playerId = payload.get("playerId");
        if (playerId == null) {
            logger.error("玩家ID为空");
            throw new RuntimeException("玩家ID不能为空");
        }

        String roomId = payload.get("roomId");
        if (roomId == null) {
            logger.error("房间ID为空");
            throw new RuntimeException("房间ID不能为空");
        }

        try {
            GameState gameState = gameService.startGame(roomId, playerId);
            logger.info("游戏开始成功: roomId={}, playerId={}, state={}", roomId, playerId, gameState);
            messagingTemplate.convertAndSend("/topic/game/" + roomId, gameState);
        } catch (Exception e) {
            logger.error("开始游戏失败: roomId={}, playerId={}, error={}", roomId, playerId, e.getMessage());
            throw new RuntimeException("开始游戏失败: " + e.getMessage());
        }
    }

    @MessageMapping("/game/become-dealer")
    public void becomeDealer(@Payload Map<String, String> payload) {
        logger.info("收到抢庄请求: payload={}", payload);
        
        String playerId = payload.get("playerId");
        if (playerId == null) {
            logger.error("玩家ID为空");
            throw new RuntimeException("玩家ID不能为空");
        }

        String roomId = payload.get("roomId");
        if (roomId == null) {
            logger.error("房间ID为空");
            throw new RuntimeException("房间ID不能为空");
        }

        try {
            GameState gameState = gameService.becomeDealer(roomId, playerId);
            logger.info("抢庄成功: roomId={}, playerId={}, state={}", roomId, playerId, gameState);
            messagingTemplate.convertAndSend("/topic/game/" + roomId, gameState);
        } catch (Exception e) {
            logger.error("抢庄失败: roomId={}, playerId={}, error={}", roomId, playerId, e.getMessage());
            throw new RuntimeException("抢庄失败: " + e.getMessage());
        }
    }

    @MessageMapping("/game/skip")
    public void skipTurn(@Payload Map<String, String> payload) {
        logger.info("收到跳过请求: payload={}", payload);
        
        String playerId = payload.get("playerId");
        if (playerId == null) {
            logger.error("玩家ID为空");
            throw new RuntimeException("玩家ID不能为空");
        }

        String roomId = payload.get("roomId");
        if (roomId == null) {
            logger.error("房间ID为空");
            throw new RuntimeException("房间ID不能为空");
        }

        try {
            GameState gameState = gameService.skipTurn(roomId, playerId);
            logger.info("跳过回合成功: roomId={}, playerId={}, state={}", roomId, playerId, gameState);
            messagingTemplate.convertAndSend("/topic/game/" + roomId, gameState);
        } catch (Exception e) {
            logger.error("跳过回合失败: roomId={}, playerId={}, error={}", roomId, playerId, e.getMessage());
            throw new RuntimeException("跳过回合失败: " + e.getMessage());
        }
    }

    @MessageMapping("/game/draw")
    public void drawCard(@Payload Map<String, String> payload) {
        logger.info("收到摸牌请求: payload={}", payload);
        
        String playerId = payload.get("playerId");
        if (playerId == null) {
            logger.error("玩家ID为空");
            throw new RuntimeException("玩家ID不能为空");
        }

        String roomId = payload.get("roomId");
        if (roomId == null) {
            logger.error("房间ID为空");
            throw new RuntimeException("房间ID不能为空");
        }

        try {
            GameState gameState = gameService.drawCard(roomId, playerId);
            logger.info("摸牌成功: roomId={}, playerId={}, state={}", roomId, playerId, gameState);
            messagingTemplate.convertAndSend("/topic/game/" + roomId, gameState);
        } catch (Exception e) {
            logger.error("摸牌失败: roomId={}, playerId={}, error={}", roomId, playerId, e.getMessage());
            throw new RuntimeException("摸牌失败: " + e.getMessage());
        }
    }

    @PostMapping("/room/{roomId}/leave")
    public ResponseEntity<?> leaveRoom(@PathVariable String roomId, HttpServletRequest request) {
        try {
            String sessionId = request.getSession().getId();
            if (sessionId == null) {
                return ResponseEntity.badRequest().body(Map.of("error", "无法获取会话ID"));
            }

            Player player = gameService.getPlayerBySessionId(sessionId);
            if (player == null) {
                return ResponseEntity.badRequest().body(Map.of("error", "无法找到玩家信息"));
            }

            gameService.leaveRoom(roomId, player.getId());
            logger.info("玩家离开房间成功: roomId={}, playerId={}", roomId, player.getId());
            
            // 尝试获取房间，如果房间不存在，发送房间关闭消息
            try {
                GameRoom room = gameService.getRoom(roomId);
                if (room != null) {
                    // 如果房间还存在，广播更新给其他玩家
                    room.getPlayers().forEach(p -> {
                        Map<String, Object> playerView = room.getPlayerView(p.getId());
                        playerView.put("type", "ROOM_UPDATE");
                        messagingTemplate.convertAndSend("/topic/game/" + roomId, playerView);
                    });
                }
            } catch (IllegalArgumentException e) {
                // 房间不存在，发送房间关闭消息
                messagingTemplate.convertAndSend("/topic/game/" + roomId, Map.of(
                    "type", "ROOM_CLOSED",
                    "message", "房间已关闭"
                ));
            }
            
            return ResponseEntity.ok().build();
        } catch (Exception e) {
            logger.error("离开房间失败: {}", e.getMessage());
            return ResponseEntity.badRequest().body(Map.of("error", e.getMessage()));
        }
    }

    public void playerDisconnected() {
        int currentOnline = onlinePlayers.decrementAndGet();
        logger.info("玩家断开连接，当前在线人数: {}", currentOnline);
    }
} 